﻿//using System;
//using System.Collections.Generic;
//using System.Data;
//using System.Data.Common;
//using System.Data.Entity;
//using System.Data.Entity.Infrastructure;
//using System.Data.Entity.ModelConfiguration;
//using System.Linq;
//using System.Reflection;
//using System.ComponentModel.Composition;

//namespace Inspiration.Core.Data
//{
//    /// <summary>
//    /// Object context
//    /// </summary>
//    //[Export]
//    public class SoianObjectContext : DbContext, IDbContext
//    {
//        public SoianObjectContext(string nameOrConnectionString)
//            : base(nameOrConnectionString)
//        {
//            //((IObjectContextAdapter) this).ObjectContext.ContextOptions.LazyLoadingEnabled = true;
//        }

//        protected override void OnModelCreating(DbModelBuilder modelBuilder)
//        {
//            ////dynamically load all configuration
//            //System.Type configType = typeof(BaseEntity);   //any of your configuration classes here
//            //var typesToRegister = Assembly.GetAssembly(configType).GetTypes();
//            ////.Where(type => !String.IsNullOrEmpty(type.Namespace))
//            ////.Where(type => type.BaseType != null && type.BaseType.IsGenericType && type.BaseType.GetGenericTypeDefinition() == typeof(EntityTypeConfiguration<>));
//            //foreach (var type in typesToRegister)
//            //{
//            //    dynamic configurationInstance = Activator.CreateInstance(type);
//            //    modelBuilder.Configurations.Add(configurationInstance);
//            //}
//            ////...or do it manually below. For example,
//            ////modelBuilder.Configurations.Add(new LanguageMap());



//            base.OnModelCreating(modelBuilder);
//        }

//        /// <summary>
//        /// Attach an entity to the context or return an already attached entity (if it was already attached)
//        /// </summary>
//        /// <typeparam name="TEntity">TEntity</typeparam>
//        /// <param name="entity">Entity</param>
//        /// <returns>Attached entity</returns>
//        protected virtual TEntity AttachEntityToContext<TEntity>(TEntity entity) where TEntity : BaseEntity, new()
//        {
//            //little hack here until Entity Framework really supports stored procedures
//            //otherwise, navigation properties of loaded entities are not loaded until an entity is attached to the context
//            var alreadyAttached = Set<TEntity>().Local.Where(x => x.ID == entity.ID).FirstOrDefault();
//            if (alreadyAttached == null)
//            {
//                //attach new entity
//                Set<TEntity>().Attach(entity);
//                return entity;
//            }
//            else
//            {
//                //entity is already loaded.
//                return alreadyAttached;
//            }
//        }

//        public string CreateDatabaseScript()
//        {
//            return ((IObjectContextAdapter)this).ObjectContext.CreateDatabaseScript();
//        }

//        public new IDbSet<TEntity> Set<TEntity>() where TEntity : BaseEntity
//        {
//            return base.Set<TEntity>();
//        }

//        public IList<TEntity> ExecuteStoredProcedureList<TEntity>(string commandText, params object[] parameters) where TEntity : BaseEntity, new()
//        {
//            //HACK: Entity Framework Code First doesn't support doesn't support output parameters
//            //That's why we have to manually create command and execute it.
//            //just wait until EF Code First starts support them
//            //
//            //More info: http://weblogs.asp.net/dwahlin/archive/2011/09/23/using-entity-framework-code-first-with-stored-procedures-that-have-output-parameters.aspx

//            bool hasOutputParameters = false;
//            if (parameters != null)
//            {
//                foreach (var p in parameters)
//                {
//                    var outputP = p as DbParameter;
//                    if (outputP == null)
//                        continue;

//                    if (outputP.Direction == ParameterDirection.InputOutput ||
//                        outputP.Direction == ParameterDirection.Output)
//                        hasOutputParameters = true;
//                }
//            }



//            var context = ((IObjectContextAdapter)(this)).ObjectContext;
//            if (!hasOutputParameters)
//            {
//                //no output parameters
//                var result = this.Database.SqlQuery<TEntity>(commandText, parameters).ToList();
//                for (int i = 0; i < result.Count; i++)
//                    result[i] = AttachEntityToContext(result[i]);

//                return result;

//                //var result = context.ExecuteStoreQuery<TEntity>(commandText, parameters).ToList();
//                //foreach (var entity in result)
//                //    Set<TEntity>().Attach(entity);
//                //return result;
//            }
//            else
//            {

//                //var connection = context.Connection;
//                var connection = this.Database.Connection;
//                //Don't close the connection after command execution


//                //open the connection for use
//                if (connection.State == ConnectionState.Closed)
//                    connection.Open();
//                //create a command object
//                using (var cmd = connection.CreateCommand())
//                {
//                    //command to execute
//                    cmd.CommandText = commandText;
//                    cmd.CommandType = CommandType.StoredProcedure;

//                    // move parameters to command object
//                    if (parameters != null)
//                        foreach (var p in parameters)
//                            cmd.Parameters.Add(p);

//                    //database call
//                    var reader = cmd.ExecuteReader();
//                    //return reader.DataReaderToObjectList<TEntity>();
//                    var result = context.Translate<TEntity>(reader).ToList();
//                    for (int i = 0; i < result.Count; i++)
//                        result[i] = AttachEntityToContext(result[i]);
//                    //close up the reader, we're done saving results
//                    reader.Close();
//                    return result;
//                }

//            }
//        }
//    }
//}
